/*
 * 
 *  This file is part of Sourceprojects.org Lycia Copyright 2010 noctarius
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 * 
 */
package org.sourceprojects.lycia.internal.io;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.sourceprojects.lycia.LyciaParser;
import org.sourceprojects.lycia.annotations.AfterPropertySet;
import org.sourceprojects.lycia.internal.EntityResolverImpl;
import org.sourceprojects.lycia.internal.logging.LyciaLoggerWrapper;
import org.sourceprojects.lycia.internal.platform.PlatformSchemaFactory;
import org.sourceprojects.lycia.io.LyciaReader;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;

public class LyciaXmlReader<B> implements LyciaReader<B> {
	private static final LyciaLoggerWrapper LOGGER = LyciaLoggerWrapper
			.getLogger(LyciaXmlReader.class);

	private LyciaParser<B> xmlParser;

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.sourceprojects.lycia.io.LyciaReader#getXmlParser()
	 */
	@Override
	public LyciaParser<B> getXmlParser() {
		return xmlParser;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.sourceprojects.lycia.io.LyciaReader#read(org.xml.sax.InputSource)
	 */
	@Override
	public Document read(final InputSource inputSource) throws Exception {
		final DocumentBuilder builder = createDocumentBuilder();
		builder.setEntityResolver(new EntityResolverImpl(xmlParser
				.getResourceResolver()));

		return builder.parse(inputSource);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.sourceprojects.lycia.io.LyciaReader#setXmlParser(org.sourceprojects
	 * .lycia.XmlParser)
	 */
	@Override
	public void setXmlParser(final LyciaParser<B> xmlParser) {
		this.xmlParser = xmlParser;
	}

	@AfterPropertySet
	public void afterPropertySet() {
		if (LOGGER.isDebugEnabled()) {
			LOGGER.debug("AfterPropertySet called");
		}
	}

	private DocumentBuilder createDocumentBuilder() throws Exception {
		final DocumentBuilderFactory factory = DocumentBuilderFactory
				.newInstance();

		// setting options for clean parsing
		factory.setIgnoringComments(getXmlParser().getConfigurator()
				.isIgnoringComments());
		factory.setIgnoringElementContentWhitespace(true);
		factory.setNamespaceAware(true);

		final PlatformSchemaFactory<B> schemaFactory = getXmlParser()
				.getConfigurator().getPlatformFactory()
				.newPlatformSchemaFactory();

		schemaFactory.build(factory, getXmlParser());

		return factory.newDocumentBuilder();
	}

}
